package com.huida.app.java8.unit01;

import lombok.Data;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author wangzhuangzhuang
 * @DESC:
 * @date 2022-02-01 23:13
 */

@Data
class Person{

	private String name;

	public Person(){}

	// 复制构造函数（copy constructor) 传入一个Person参数，并返回一个具有相同特性的新Person
	// 如果需要将流代码从原始实例中分离传来，复制构造函数将非常有用。
	// eg: 有一个人员列表，=》转换为流 =》 再转换为列表 =》那么引用不会发生变化
	public Person(Person p){
		this.name = p.name;
	}

	public Person(String name){
		this.name = name;
	}

	// 构造函数Person传入String的可变参数列表
	// 传入0个或多个字符串参数，并使用空格作为定界符将这些参数拼接在一起
	// 如何调用这个构造函数？任何传入0个或多个字符串参数的客户端都会调用这个构造函数。
	// 一种方案是利用String类定义的split方法传入一个定界符并返回一个String数组
	public Person(String... names){
		this.name = Arrays.stream(names).collect(Collectors.joining(" "));
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}
public class DemoTest02 {
	public static void main(String[] args) {
		// ================================================================================================================
		// 将字符串转换为Person实例
		List<String> names = Arrays.asList("Grace Hopper", "Barbara Liskov", "Ada LoveLace", "Karen Spark Jones");

		List<Person> people = names.stream()
				.map(name -> new Person(name)) // .map(Person::new)
				.collect(Collectors.toList());

		// [Person(name=Grace Hopper), Person(name=Barbara Liskov), Person(name=Ada LoveLace), Person(name=Karen Spark Jones)]
		System.out.println(people);

		// ===============================================================================================================
		// 将列表转换为流，再转换回列表
		Person before = new Person("Grace Hopper");
		List<Person> peoplePlus = Stream.of(before)
										.collect(Collectors.toList());

		Person after = peoplePlus.get(0);

		System.out.println("before == after: " + (before == after));

		before.setName("Grace Murray Hopper");
		System.out.println("after's name: " + after.getName());

		// 使用复制构造函数
		// ===============================================================================================================
		List<Person> peoplePlus001 = Stream.of(before)
											.map(Person::new) // 通过复制构造函数来切断两者之间的连接
											.collect(Collectors.toList());
		after = peoplePlus001.get(0);
		System.out.println("after == before: " + (before == after)); // after == before: false
		System.out.println("before's name: "+ before.getName());
		System.out.println("after's name: " + after.getName());

		// 可变参数构造函数(varargs constructor)
		// ===============================================================================================================
		// 可变参数的应用
		names.stream()
				.map(name -> name.split(" "))
				.map(Person::new)
				.collect(Collectors.toList());
		// 1. 创建字符串流
		// 2. 映射到字符串数组流
		// 3. 映射到Person流
		// 4. 收集到Person列表
		// map方法的上下文包含Person::new构造函数引用，它是一个字符串数组流
		// 将调用可变参数构造函数。
	}
}